<template>
  <div :class="{'ly-is-full':isFull}">
    <div class="tableSelect" ref="tableSelect">
      <el-form :inline="true" :model="searchForm" label-position="left">
        <el-form-item label="关键词：">
          <el-input
            size="default"
            clearable
            v-model.trim="searchForm.keyword"
            maxlength="60"
            placeholder="关键词"
            @change="handleSearch"
            style="width:200px"
          ></el-input>
        </el-form-item>
        <el-form-item label="文件类型：">
          <el-select
            size="default"
            v-model="searchForm.file_type"
            clearable
            placeholder="请选择"
            @change="handleSearch"
            style="width:120px"
          >
            <el-option label="图片" value="jpg,jpeg,png,gif,webp" />
            <el-option label="文档" value="pdf,doc,docx,txt" />
            <el-option label="音频" value="mp3,wav,ogg" />
            <el-option label="视频" value="mp4,avi,mov" />
            <el-option label="压缩包" value="zip,rar,7z" />
          </el-select>
        </el-form-item>
        <el-form-item label="查看模式：" v-if="isAdmin">
          <el-select
            size="default"
            v-model="viewMode"
            placeholder="请选择"
            @change="handleModeChange"
            style="width:120px"
          >
            <el-option label="我的文件" :value="false" />
            <el-option label="所有文件" :value="true" />
          </el-select>
        </el-form-item>
        <el-form-item label=""><el-button @click="handleSearch" type="primary" icon="Search">查询</el-button></el-form-item>
        <el-form-item label=""><el-button @click="resetSearch" icon="Refresh">重置</el-button></el-form-item>
        <el-form-item label="">
          <el-button type="primary" @click="uploadDialogVisible = true" icon="Plus">上传文件</el-button>
        </el-form-item>
        <el-form-item label="" v-if="selectedFiles.length > 0">
          <el-button type="danger" @click="batchDelete">
            <el-icon><Delete /></el-icon>
            批量删除 ({{ selectedFiles.length }})
          </el-button>
        </el-form-item>
      </el-form>
    </div>

      <el-table
      :max-height="tableHeight"
      border
      row-key="id"
        :data="fileList"
      ref="tableRef"
        v-loading="tableLoading"
      style="width: 100%;"
        @selection-change="handleSelectionChange"
      >
        <el-table-column type="selection" width="55" />
      <el-table-column type="index" width="70" label="序号">
        <template #default="scope">
          <span v-text="getIndex(scope.$index)"></span>
        </template>
      </el-table-column>
      <el-table-column min-width="80" label="预览">
          <template #default="{ row }">
            <div class="file-preview">
              <img
                v-if="isImage(row.file_type)"
                :src="getFilePreview(row)"
                :alt="row.original_name"
                class="preview-image"
                @click="handlePreviewFile(row)"
              />
              <el-icon v-else class="file-icon" @click="handlePreviewFile(row)">
                <Document v-if="isDocument(row.file_type)" />
                <VideoPlay v-else-if="isVideo(row.file_type)" />
                <Headset v-else-if="isAudio(row.file_type)" />
                <Box v-else-if="isArchive(row.file_type)" />
                <Files v-else />
              </el-icon>
            </div>
          </template>
        </el-table-column>
      <el-table-column min-width="200" prop="original_name" label="文件名" show-overflow-tooltip>
          <template #default="{ row }">
            <div class="file-name">
              <span :title="row.original_name">{{ row.original_name }}</span>
            </div>
          </template>
        </el-table-column>
      <el-table-column min-width="80" prop="file_type" label="文件类型">
          <template #default="{ row }">
            <el-tag size="small">{{ row.file_type.toUpperCase() }}</el-tag>
          </template>
        </el-table-column>
      <el-table-column min-width="100" prop="file_size" label="文件大小">
          <template #default="{ row }">
            {{ formatFileSize(row.file_size) }}
          </template>
        </el-table-column>
      <el-table-column min-width="160" prop="created_at" label="上传时间">
          <template #default="{ row }">
            {{ formatDate(row.created_at) }}
          </template>
        </el-table-column>
      <el-table-column label="操作" fixed="right" width="200">
        <template #header>
          <div style="display: flex;justify-content: space-between;align-items: center;">
            <div>操作</div>
            <div @click="setFull">
              <el-tooltip content="全屏" placement="bottom">
                <el-icon><FullScreen /></el-icon>
              </el-tooltip>
            </div>
          </div>
        </template>
          <template #default="{ row }">
          <span class="table-operate-btn" @click="downloadFile(row)">下载</span>
          <span class="table-operate-btn" @click="copyFileUrl(row)">复制链接</span>
          <span class="table-operate-btn" @click="deleteFile(row)">删除</span>
          </template>
        </el-table-column>
      </el-table>

      <!-- 分页 -->
      <div class="pagination">
        <el-pagination
          v-model:current-page="pagination.page"
          v-model:page-size="pagination.limit"
          :page-sizes="[10, 20, 50, 100]"
          :total="pagination.total"
          layout="total, sizes, prev, pager, next, jumper"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
    </div>

    <!-- 文件上传对话框 -->
    <el-dialog
      v-model="uploadDialogVisible"
      title="上传文件"
      width="600px"
      @close="resetUploadDialog"
    >
      <div class="upload-section">
        <el-form :model="uploadForm" label-width="100px">
          <el-form-item label="选择文件">
            <el-upload
              ref="uploadRef"
              :auto-upload="false"
              :on-change="handleFileChange"
              :before-upload="beforeUpload"
              :limit="10"
              :file-list="uploadForm.files"
              drag
              multiple
            >
              <el-icon class="el-icon--upload"><upload-filled /></el-icon>
              <div class="el-upload__text">
                将文件拖拽到此处，或<em>点击上传</em>
              </div>
              <template #tip>
                <div class="el-upload__tip">
                  支持jpg/png/gif/pdf/doc/txt等格式，单个文件不超过10MB
                </div>
              </template>
            </el-upload>
          </el-form-item>
        </el-form>
      </div>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="uploadDialogVisible = false">取消</el-button>
          <el-button type="primary" @click="handleUpload" :loading="uploading">
            {{ uploading ? '上传中...' : '开始上传' }}
          </el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 文件预览对话框 -->
    <el-dialog
      v-model="previewDialogVisible"
      :title="previewFile?.original_name"
      width="800px"
      @close="previewFile = null"
    >
      <div class="file-preview-content">
        <img
          v-if="previewFile && isImage(previewFile.file_type)"
          :src="getFilePreview(previewFile)"
          :alt="previewFile.original_name"
          style="max-width: 100%; max-height: 600px;"
        />
        <div v-else class="unsupported-preview">
          <el-icon size="64"><Files /></el-icon>
          <p>此文件类型不支持预览</p>
          <el-button type="primary" @click="downloadFile(previewFile)">
            下载文件
          </el-button>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { ref, reactive, onMounted, nextTick, onUnmounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import {
  Upload,
  Download,
  Delete,
  Search,
  Document,
  VideoPlay,
  Headset,
  Box,
  Files,
  UploadFilled,
  FullScreen
} from '@element-plus/icons-vue'
import { fileApi } from '@/api/file'
import { getTableHeight } from "@/utils/util";

export default {
  name: 'FileManage',
  components: {
    Upload,
    Download,
    Delete,
    Search,
    Document,
    VideoPlay,
    Headset,
    Box,
    Files,
    UploadFilled,
    FullScreen
  },
  setup() {
    // 响应式数据
    const fileList = ref([])
    const tableHeight = ref(260)
    const tableRef = ref(null)
    const tableSelect = ref(null)
    const tableLoading = ref(false)
    const selectedFiles = ref([])
    const uploadDialogVisible = ref(false)
    const previewDialogVisible = ref(false)
    const previewFile = ref(null)
    const uploading = ref(false)
    const uploadRef = ref(null)
    const isAdmin = ref(false)
    const isAdminMode = ref(false)
    const viewMode = ref(false)
    const isFull = ref(false)

    // 搜索表单
    const searchForm = reactive({
      keyword: '',
      file_type: ''
    })

    // 分页
    const pagination = reactive({
      page: 1,
      limit: 20,
      total: 0
    })

    // 上传表单
    const uploadForm = reactive({
      files: []
    })

    // 表格序列号
    const getIndex = ($index) => {
      // (当前页 - 1) * 当前显示数据条数 + 当前行数据的索引 + 1
      return (pagination.page - 1) * pagination.limit + $index + 1
    }

    // 全屏/退出全屏
    const setFull = () => {
      isFull.value = !isFull.value
    }

    // 重置搜索
    const resetSearch = () => {
      searchForm.keyword = ''
      searchForm.file_type = ''
      viewMode.value = false
      isAdminMode.value = false
      pagination.page = 1
      getFileList()
    }

    // 获取文件列表
    const getFileList = async () => {
      try {
        tableLoading.value = true
        const params = {
          page: pagination.page,
          limit: pagination.limit,
          keyword: searchForm.keyword,
          file_type: searchForm.file_type
        }

        console.log('开始获取文件列表，参数:', params)
        console.log('当前模式:', isAdminMode.value ? '管理员模式' : '普通用户模式')

        // 根据当前模式选择不同的API
        let response
        if (isAdminMode.value) {
          console.log('调用管理员API获取所有文件')
          response = await fileApi.getAllFiles(params)
        } else {
          console.log('调用公开文件API获取文件列表')
          response = await fileApi.getPublicFiles(params)
        }

        console.log('API响应:', response)

        if (response.code === 200) {
          fileList.value = response.data.data
          pagination.total = response.data.total
          console.log(`成功获取${fileList.value.length}个文件，总数:${pagination.total}`)
        } else {
          ElMessage.error(response.message || '获取文件列表失败')
          console.error('获取文件列表失败:', response.message)
        }
      } catch (error) {
        ElMessage.error('获取文件列表失败')
        console.error('获取文件列表异常:', error)
      } finally {
        tableLoading.value = false
      }
    }

    // 搜索处理
    const handleSearch = () => {
      pagination.page = 1
      getFileList()
    }

    // 分页处理
    const handleSizeChange = (val) => {
      pagination.limit = val
      pagination.page = 1
      getFileList()
    }

    const handleCurrentChange = (val) => {
      pagination.page = val
      getFileList()
    }

    // 选择文件
    const handleSelectionChange = (selection) => {
      selectedFiles.value = selection
    }

    // 文件上传相关
    const handleFileChange = (file, fileList) => {
      uploadForm.files = fileList
    }

    const beforeUpload = (file) => {
      const isValidSize = file.size / 1024 / 1024 < 10
      if (!isValidSize) {
        ElMessage.error('文件大小不能超过10MB!')
        return false
      }
      return true
    }

    const handleUpload = async () => {
      if (uploadForm.files.length === 0) {
        ElMessage.warning('请选择要上传的文件')
        return
      }

      try {
        uploading.value = true
        const promises = uploadForm.files.map(file => {
          return fileApi.uploadFile(file.raw)
        })

        const results = await Promise.all(promises)
        const successCount = results.filter(result => result.code === 200).length

        if (successCount === uploadForm.files.length) {
          ElMessage.success('所有文件上传成功')
        } else {
          ElMessage.warning(`${successCount}/${uploadForm.files.length} 个文件上传成功`)
        }

        uploadDialogVisible.value = false
        getFileList()
      } catch (error) {
        ElMessage.error('文件上传失败')
        console.error('文件上传异常:', error)
      } finally {
        uploading.value = false
      }
    }

    const resetUploadDialog = () => {
      uploadForm.files = []
      if (uploadRef.value) {
        uploadRef.value.clearFiles()
      }
    }

    // 文件下载
    const downloadFile = async (file) => {
      try {
        file.downloading = true
        const response = await fileApi.downloadFile(file.id)

        // 创建下载链接
        const url = window.URL.createObjectURL(new Blob([response]))
        const link = document.createElement('a')
        link.href = url
        link.download = file.original_name
        document.body.appendChild(link)
        link.click()
        document.body.removeChild(link)
        window.URL.revokeObjectURL(url)

        ElMessage.success('下载成功')
      } catch (error) {
        ElMessage.error('下载失败')
        console.error(error)
      } finally {
        file.downloading = false
      }
    }

    // 文件删除
    const deleteFile = async (file) => {
      try {
        await ElMessageBox.confirm('确定要删除这个文件吗？', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        })

        file.deleting = true
        const response = await fileApi.deleteFile(file.id)
        if (response.code === 200) {
          ElMessage.success('删除成功')
          getFileList()
        } else {
          // 根据错误代码提供不同的提示
          if (response.code === 403) {
            ElMessage.error('无权限删除此文件，请联系管理员或使用管理员模式')
        } else {
          ElMessage.error(response.message || '删除失败')
          }
        }
      } catch (error) {
        if (error !== 'cancel') {
          console.error('删除文件失败:', error)
          ElMessage.error('删除失败')
        }
      } finally {
        file.deleting = false
      }
    }

    // 文件预览
    const handlePreviewFile = (file) => {
      previewFile.value = file
      previewDialogVisible.value = true
    }

    // 工具函数
    const isImage = (fileType) => {
      return ['jpg', 'jpeg', 'png', 'gif', 'webp'].includes(fileType.toLowerCase())
    }

    const isDocument = (fileType) => {
      return ['pdf', 'doc', 'docx', 'txt', 'xls', 'xlsx', 'ppt', 'pptx'].includes(fileType.toLowerCase())
    }

    const isVideo = (fileType) => {
      return ['mp4', 'avi', 'mov', 'wmv', 'flv', 'webm'].includes(fileType.toLowerCase())
    }

    const isAudio = (fileType) => {
      return ['mp3', 'wav', 'ogg', 'aac', 'flac'].includes(fileType.toLowerCase())
    }

    const isArchive = (fileType) => {
      return ['zip', 'rar', '7z', 'tar', 'gz'].includes(fileType.toLowerCase())
    }

    const getFilePreview = (file) => {
      // 如果是图片，返回下载链接作为预览
      return file.file_url || `http://127.0.0.1:5000/api/files/download/${file.id}`
    }

    const formatFileSize = (bytes) => {
      if (bytes === 0) return '0 Bytes'
      const k = 1024
      const sizes = ['Bytes', 'KB', 'MB', 'GB']
      const i = Math.floor(Math.log(bytes) / Math.log(k))
      return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
    }

    const formatDate = (dateString) => {
      const date = new Date(dateString)
      return date.toLocaleString('zh-CN')
    }

    const getUploadTypeLabel = (type) => {
      const labels = {
        avatar: '头像',
        photo: '照片',
        document: '文档',
        general: '其他'
      }
      return labels[type] || type
    }

    // 检查当前用户是否为管理员
    const checkIsAdmin = () => {
      // 从localStorage或sessionStorage中获取用户信息
      const userInfo = JSON.parse(localStorage.getItem('userInfo') || sessionStorage.getItem('userInfo') || '{}')
      // 判断是否为管理员（根据实际项目调整判断条件）
      isAdmin.value = userInfo.is_admin === 1 || userInfo.is_superuser === 1 || userInfo.role_name === '超级管理员'
      console.log('当前用户是否为管理员:', isAdmin.value)
    }

    // 处理模式切换
    const handleModeChange = () => {
      isAdminMode.value = viewMode.value
      pagination.page = 1
      getFileList()
    }

    // 计算表格高度
    const getTheTableHeight = () => {
      tableHeight.value = getTableHeight(tableSelect.value?.offsetHeight - 50)
    }

    const listenResize = () => {
      nextTick(() => {
        getTheTableHeight()
      })
    }

    // 批量删除
    const batchDelete = async () => {
      try {
        await ElMessageBox.confirm(`确定要删除选中的 ${selectedFiles.value.length} 个文件吗？`, '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        })

        const promises = selectedFiles.value.map(file => fileApi.deleteFile(file.id))
        const results = await Promise.all(promises)
        const successCount = results.filter(result => result.code === 200).length

        if (successCount === selectedFiles.value.length) {
          ElMessage.success('批量删除成功')
        } else {
          ElMessage.warning(`${successCount}/${selectedFiles.value.length} 个文件删除成功`)
        }

        selectedFiles.value = []
        getFileList()
      } catch (error) {
        if (error !== 'cancel') {
          ElMessage.error('批量删除失败')
          console.error('批量删除失败:', error)
        }
      }
    }

    // 复制文件URL
    const copyFileUrl = (file) => {
      const url = file.file_url || `http://127.0.0.1:5000/api/files/download/${file.id}`
      navigator.clipboard.writeText(url).then(() => {
        ElMessage.success('文件链接已复制到剪贴板')
      }).catch(() => {
        ElMessage.error('复制失败，请手动复制')
      })
    }

    // 生命周期
    onMounted(() => {
      checkIsAdmin()
      getFileList()
      // 监听页面宽度变化搜索框的高度
      window.addEventListener('resize', listenResize)
      nextTick(() => {
        getTheTableHeight()
      })
    })

    // 页面销毁
    onUnmounted(() => {
      // 页面销毁，去掉监听事件
      window.removeEventListener("resize", listenResize)
    })

    return {
      fileList,
      tableLoading,
      selectedFiles,
      uploadDialogVisible,
      previewDialogVisible,
      previewFile,
      uploading,
      uploadRef,
      searchForm,
      pagination,
      uploadForm,
      getFileList,
      handleSearch,
      handleSizeChange,
      handleCurrentChange,
      handleSelectionChange,
      handleFileChange,
      beforeUpload,
      handleUpload,
      resetUploadDialog,
      downloadFile,
      deleteFile,
      handlePreviewFile,
      isImage,
      isDocument,
      isVideo,
      isAudio,
      isArchive,
      getFilePreview,
      formatFileSize,
      formatDate,
      getUploadTypeLabel,
      isAdmin,
      isAdminMode,
      handleModeChange,
      tableHeight,
      tableRef,
      tableSelect,
      viewMode,
      isFull,
      setFull,
      resetSearch,
      getIndex,
      batchDelete,
      copyFileUrl
    }
  }
}
</script>

<style lang="scss" scoped>
.tableSelect {
  overflow: hidden;
  margin-bottom: 8px;
}

.pagination {
    display: flex;
  justify-content: center;
    padding: 20px;
    background: white;
}

    .file-preview {
      display: flex;
      align-items: center;
      justify-content: center;
      cursor: pointer;

      .preview-image {
        width: 60px;
        height: 60px;
        object-fit: cover;
        border-radius: 4px;
        border: 1px solid #ddd;
      }

      .file-icon {
        font-size: 32px;
        color: #606266;
      }
    }

    .file-name {
      display: flex;
      align-items: center;
      gap: 8px;

      span {
        flex: 1;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
  }

  .file-preview-content {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 300px;

    .unsupported-preview {
      display: flex;
      flex-direction: column;
      align-items: center;
      gap: 16px;
      color: #909399;

      p {
        margin: 0;
        font-size: 16px;
      }
    }
  }


.table-operate-btn {
  cursor: pointer;
  color: #409EFF;
  margin-right: 10px;
  font-size: 14px;

  &:hover {
    color: #66b1ff;
  }
}

.upload-section {
  .el-upload {
    width: 100%;
  }

  .el-upload-dragger {
    width: 100%;
    height: 200px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
  }
}

/* 全屏样式 */
.ly-is-full {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 1000;
  background-color: #fff;
  padding: 20px;
  box-sizing: border-box;
}
</style>
